/*
 * SPDX-License-Identifier: Apache-2.0
 * Copyright Blazebit
 */

package com.blazebit.persistence.view.impl.objectbuilder.transformer.correlation;

import com.blazebit.persistence.FullQueryBuilder;
import com.blazebit.persistence.ObjectBuilder;
import com.blazebit.persistence.view.impl.EntityViewConfiguration;
import com.blazebit.persistence.view.impl.EntityViewManagerImpl;
import com.blazebit.persistence.view.spi.EmbeddingViewJpqlMacro;
import com.blazebit.persistence.view.impl.metamodel.ManagedViewTypeImplementor;
import com.blazebit.persistence.view.impl.metamodel.MappingConstructorImpl;

/**
 *
 * @author Christian Beikov
 * @since 1.2.0
 */
public final class SubviewCorrelator implements Correlator {

    private final ManagedViewTypeImplementor<?> managedViewType;
    private final MappingConstructorImpl<?> mappingConstructor;
    private final EntityViewManagerImpl evm;
    private final String viewName;
    private final String attributePath;

    public SubviewCorrelator(ManagedViewTypeImplementor<?> managedViewType, MappingConstructorImpl<?> mappingConstructor, EntityViewManagerImpl evm, String viewName, String attributePath) {
        this.managedViewType = managedViewType;
        this.mappingConstructor = mappingConstructor;
        this.evm = evm;
        this.viewName = viewName;
        this.attributePath = attributePath;
    }

    @Override
    public int getElementOffset() {
        return managedViewType.getInheritanceSubtypeConfiguration(null).hasSubtypes() ? 1 : 0;
    }

    @Override
    @SuppressWarnings({"rawtypes", "unchecked"})
    public ObjectBuilder<?> finish(FullQueryBuilder<?, ?> criteriaBuilder, EntityViewConfiguration entityViewConfiguration, int offset, int tupleSuffix, String correlationRoot, EmbeddingViewJpqlMacro embeddingViewJpqlMacro, boolean nullFlatViewIfEmpty) {
        EntityViewConfiguration subviewConfiguration = entityViewConfiguration.forSubview(criteriaBuilder, attributePath, embeddingViewJpqlMacro);
        ObjectBuilder builder = evm.createObjectBuilder(managedViewType, mappingConstructor, correlationRoot, attributePath, criteriaBuilder, subviewConfiguration, offset, tupleSuffix, nullFlatViewIfEmpty);
        criteriaBuilder.selectNew(builder);
        return builder;
    }
}
